/*
 * @Author: pengtianrui 2276608413@qq.com
 * @Date: 2024-08-26 16:04:21
 * @LastEditors: pengtianrui pengtianrui@outlook.com
 * @LastEditTime: 2025-02-13 10:52:46
 * @FilePath: \SGFEM\DataStructure\FEM\Load\include\PLOAD1Data.h
 */

#pragma once
#include "Utility/Logging/SGLogger.h"
#include "Utility/Algebra/Matrix.h"

#include "DataStructure/Common/DataStructureExport.h"
#include "DataStructure/Common/DataStructureNamespace.h"
#include "DataStructure/Common/Id.h"
#include "DataStructure/Common/Real.h"
#include "DataStructure/Common/EpZero.h"
#include "DataStructure/Common/SetBase.h"
#include "DataStructure/Input/Load/LoadTypes.h"

SG_DATASTRUCTURE_FEM_NAMESPACE_OPEN
struct DECLSPEC PLOAD1Data : public SetBase
{
    static SG::DataStructure::FEM::LoadType GetType ()
    {
        return SG::DataStructure::FEM::LoadType::LOAD_PLOAD1;
    };
    
    /** @brief   载荷是否是集中力
     *  
     * @author   wanghuan
     * @date     2025.02.21
     */
    bool Isconcentration () const;

    bool isForce() const;

    bool isBasicCoord() const;

    SG::Algebra::Matrix getLoad(const SG::Algebra::Matrix& T) const;

    SG::DataStructure::Common::Id   m_eId      = 0;    ///< 单元Id
    SG::DataStructure::Common::Id   m_type     = 0;    ///< 载荷类型
    SG::DataStructure::Common::I64  m_scale    = 0;    ///< 确定比例因子
    SG::DataStructure::Common::Real m_x1       = 0.0;  ///< 沿单元轴距离端点A的距离
    SG::DataStructure::Common::Real m_p1       = 0.0;  ///< 位置上的负载系数
    SG::DataStructure::Common::Real m_x2       = 0.0;  ///< 沿单元轴距离端点A的距离
    SG::DataStructure::Common::Real m_p2       = 0.0;  ///< 位置上的负载系数
    SG::DataStructure::Common::Id   m_domainId = 0;
};

///< 作用到单元上的是线力还是分布力
inline bool PLOAD1Data::Isconcentration () const
{
    return fabs(m_x1 - m_x2) < SG::DataStructure::Common::EP_ZERO || fabs(m_x2) < SG::DataStructure::Common::EP_ZERO;
}

// 判断荷载类型是否为力，若不是则为弯矩
inline bool PLOAD1Data::isForce() const
{
    return (m_type <= 6);
}


// 判断荷载加载坐标系是否为基础坐标系，若不是则为单元坐标系
inline bool PLOAD1Data::isBasicCoord() const
{
    int J = m_type % 6;
    return (J >= 1 && J <= 3);
}

/**
 * @brief    获得荷载矩阵，大小(6, 1)，前3个元素为F1，后三个向量为F2
 *           
 * @param    T 荷载方向转换矩阵（basic坐标系 ->单元局部坐标系）
 * 
 * @return   荷载矩阵，大小(6, 1)
 */
inline SG::Algebra::Matrix PLOAD1Data::getLoad(const SG::Algebra::Matrix& T) const
{
    SG::Algebra::Matrix load(6, 1); 
    int J = m_type % 6;

    switch (J)
    {
        case 1: // for through
        case 2: // for through
        case 3:
            load = SG::Algebra::Matrix(6, 1, {T(0,J-1) * m_p1, T(1,J-1) * m_p1, T(2,J-1) * m_p1,
                                       T(0,J-1) * m_p2, T(1,J-1) * m_p2, T(2,J-1) * m_p2});

            break;
        
        case 4:
            load = SG::Algebra::Matrix(6, 1, {m_p1, 0.0, 0.0,
                                       m_p2, 0.0, 0.0});
            break;

        case 5:
            load = SG::Algebra::Matrix(6, 1, {0.0, m_p1, 0.0,
                                       0.0, m_p2, 0.0});
            break;

        case 0:
            load = SG::Algebra::Matrix(6, 1, {0.0, 0.0, m_p1,
                                       0.0, 0.0, m_p2});
            break;
        default:
            SGError << "The input type in the PLoad1 entry is incorrect, which is " << m_type;
            break;
    }

    return load;
}



using PLOAD1Array = std::vector<SG::DataStructure::FEM::PLOAD1Data>;
DECLSPEC bool operator== (const PLOAD1Data& a, const PLOAD1Data& b);
SG_DATASTRUCTURE_FEM_NAMESPACE_CLOSE